package sunbao.ido.xsd;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Classname XSDReader2
 * @Description
 * @Date 2020/03/19 15:04
 * @Created by Administrator
 */
public class XSDReader2 {

    private static void replaceRef(Element root, Element child, String xsdPath, List<XSDNode> list) {
        List<Node> elements = child.selectNodes(".//xs:element[@ref]");
        // 获取 attribute 属性
        List<Node> attributes = child.selectNodes(".//xs:attribute");
        attributes.forEach(item -> {
            Element itemEle = (Element) item;
            XSDNode xsdNode = new XSDNode();
            String xpathcopy = xsdPath;
            xsdNode.setXPath(xpathcopy + "/@" + itemEle.attributeValue(XMLConstants.XSD_ATTRIBUTE_NAME));
            xsdNode.setName(itemEle.attributeValue(XMLConstants.XSD_ATTRIBUTE_NAME));
            xsdNode.setType(itemEle.attributeValue(XMLConstants.XSD_ATTRIBUTE_TYPE));
            xsdNode.setIsUnbounded(itemEle.attributeValue(XMLConstants.XSD_ATTRIBUTE_MAXOCCURS));
            list.add(xsdNode);
        });
        // 如果没有ref 则表示当前节点为叶子节点
        if (CollectionUtils.isEmpty(elements)) {
            return;
        }
        elements.forEach(item -> {
            Element itemNode = (Element) item;
            String name = itemNode.attributeValue(XMLConstants.XSD_ATTRIBUTE_REF);
            // 获取ref节点
            String basePath = XMLConstants.DOUBELROOTSPER + XMLConstants.XSD_DEFAULT_NAMESPACE + ":element[@name=\"" + name + "\"]";
            Element refnode = (Element) root.selectSingleNode(basePath);
            // 处理ref节点
            // 组装下一个element元素的XPath
            String currentXsdPath = xsdPath + "/" + name;
            replaceRef(root, refnode, currentXsdPath, list);
        });
    }

    public static List<XSDNode> dealRefNode(String xsd) throws DocumentException {
        Element root = getRootElement(xsd);
        return dealRefNode(root);
    }

    public static List<XSDNode> dealRefNode(File xsd) throws DocumentException {
        Element root = getRootElement(xsd);
        return dealRefNode(root);
    }

    private static List<XSDNode> dealRefNode(Element root) {
        String basePath = XMLConstants.DOUBELROOTSPER + XMLConstants.XSD_DEFAULT_NAMESPACE + ":element[@name=\"" + XMLConstants.MESSAGE + "\"]";
        Element application = (Element) root.selectSingleNode(basePath);
        List<XSDNode> list = new ArrayList<>();
        replaceRef(root, application, XMLConstants.ROOTSPER + XMLConstants.MESSAGE, list);
        return list;
    }

    private static Element getRootElement(String xsd) throws DocumentException {
        SAXReader saxReader = inintSaxReader();
        Document doc = saxReader.read(xsd);
        return doc.getRootElement();
    }

    private static Element getRootElement(File xsd) throws DocumentException {
        SAXReader saxReader = inintSaxReader();
        Document doc = saxReader.read(xsd);
        return doc.getRootElement();
    }

    private static SAXReader inintSaxReader() {
        SAXReader saxReader = new SAXReader();
        Map<String, String> ns = new HashMap<>();
        ns.put(XMLConstants.XSD_DEFAULT_NAMESPACE, XMLConstants.NAMESPACEADDRESS);
        saxReader.getDocumentFactory().setXPathNamespaceURIs(ns);
        return saxReader;
    }
}
